keyhandler: global shared scratch space for temporary strings
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 11 Feb 2010 21:08:06 +0000 (21:08 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 11 Feb 2010 21:08:06 +0000 (21:08 +0000)
Put one static definition in one place and we can make it as big as we
think reasonable.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/keyhandler.c
xen/common/sched_credit.c
xen/include/xen/keyhandler.h

index 9b4d6b7f120df4de0f3350233fb4a2297cd3c568..78daf45a3def8bc11401819514848ac519592223 100644 (file)
 static struct keyhandler *key_table[256];
 static unsigned char keypress_key;
 
+char keyhandler_scratch[100];
+
 static void keypress_action(unsigned long unused)
 {
-    unsigned char key = keypress_key;
-    console_start_log_everything();
-    if ( key_table[key] != NULL )
-        (*key_table[key]->u.fn)(key);
-    console_end_log_everything();
+    handle_keypress(keypress_key, NULL);
 }
 
 static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0);
 
 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
 {
+    static bool_t executing_handler;
     struct keyhandler *h;
 
     if ( (h = key_table[key]) == NULL )
@@ -40,9 +39,18 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
 
     if ( !in_irq() || h->irq_callback )
     {
+        /*
+         * No concurrent handler execution: prevents garbled console and
+         * protects keyhandler_scratch[].
+         */
+        if ( test_and_set_bool(executing_handler) )
+            return;
+        wmb();
         console_start_log_everything();
-        (*h->u.irq_fn)(key, regs);
+        h->irq_callback ? (*h->u.irq_fn)(key, regs) : (*h->u.fn)(key);
         console_end_log_everything();
+        wmb();
+        executing_handler = 0;
     }
     else
     {
@@ -174,7 +182,7 @@ static void dump_domains(unsigned char key)
     struct domain *d;
     struct vcpu   *v;
     s_time_t       now = NOW();
-    char           tmpstr[100];
+#define tmpstr keyhandler_scratch
 
     printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
            (u32)(now>>32), (u32)now);
@@ -234,6 +242,7 @@ static void dump_domains(unsigned char key)
     }
 
     rcu_read_unlock(&domlist_read_lock);
+#undef tmpstr
 }
 
 static struct keyhandler dump_domains_keyhandler = {
index 8059bf131225abf9c964560b678fc766b33c428f..b0ccb0ccacb3376de550e464a9bab00d02a5897d 100644 (file)
@@ -21,6 +21,7 @@
 #include <xen/softirq.h>
 #include <asm/atomic.h>
 #include <xen/errno.h>
+#include <xen/keyhandler.h>
 
 /*
  * CSCHED_STATS
@@ -1241,7 +1242,7 @@ csched_dump_pcpu(int cpu)
     struct csched_pcpu *spc;
     struct csched_vcpu *svc;
     int loop;
-    char cpustr[100];
+#define cpustr keyhandler_scratch
 
     spc = CSCHED_PCPU(cpu);
     runq = &spc->runq;
@@ -1269,6 +1270,7 @@ csched_dump_pcpu(int cpu)
             csched_dump_vcpu(svc);
         }
     }
+#undef cpustr
 }
 
 static void
@@ -1276,7 +1278,7 @@ csched_dump(void)
 {
     struct list_head *iter_sdom, *iter_svc;
     int loop;
-    char idlers_buf[100];
+#define idlers_buf keyhandler_scratch
 
     printk("info:\n"
            "\tncpus              = %u\n"
@@ -1323,6 +1325,7 @@ csched_dump(void)
             csched_dump_vcpu(svc);
         }
     }
+#undef idlers_buf
 }
 
 static void
index 71e6dbe11c0771ab16381c5ee9355cbcbb83e6c3..1670d7d7f9977f3132bc2f886827844d92415f62 100644 (file)
@@ -52,4 +52,7 @@ extern void register_keyhandler(unsigned char key, struct keyhandler *handler);
 /* Inject a keypress into the key-handling subsystem. */
 extern void handle_keypress(unsigned char key, struct cpu_user_regs *regs);
 
+/* Scratch space is available for use of any keyhandler. */
+extern char keyhandler_scratch[100];
+
 #endif /* __XEN_KEYHANDLER_H__ */